//
//  DnSuperImageView.m
//  DnImageCropper
//
//  Created by Ngoc on 09/12/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//
#define ZOOM_STEP 1.5
#define kMaxRedoOperator 10
#import "DnSuperImageView.h"
#import "UIImage+RawData.h"
@interface NSMutableArray (Stack)
-(void) push:(id) object;
-(id) pop;
@end
@implementation NSMutableArray (Stack)

-(void) push:(id) object
{
    if ([self count] == kMaxRedoOperator-1) {
        [self removeObjectAtIndex:0];
    }
    [self addObject:object];
}
-(id) pop
{
    id object = nil;
    if ([self count]>0) {
        object  = [[[self lastObject]retain]autorelease];
        [self removeLastObject];
    }
    return object;
}

@end

@interface DnSuperImageView(Private)

-(void) setUpWithDefaultValue;
-(void) updateScrollView:(BOOL) isSetZoomScale;
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center;
-(void) changeImageSizeAndUpdateScrollView;
- (void) sliderMoved:(float) newValue;
-(void) saveImageToUndo:(UIImage*) repairingImage;
-(void) redo;
-(void) undo;
@end


@implementation DnSuperImageView
@synthesize resizeStrategy =_resizeStrategy;
@synthesize currentSliderValue = _currentSliderValue;
@synthesize image=_image;
@synthesize fliter =_filter;

- (id)initWithFrame:(CGRect)frame image:(UIImage*) image	
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setUpWithDefaultValue]; 
        if (image) {
            _imageView = [[UIImageView alloc] initWithImage:image];
        }
        _imageView.userInteractionEnabled = YES;
        _imageView.frame = CGRectMake(0,0, _imageView.image.size.width, _imageView.image.size.height);
        
        _scrollView = [[NYOBetterZoomUIScrollView alloc] initWithChildView:_imageView];
        _scrollView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        _scrollView.delegate = self;
        _scrollView.childView = _imageView;
        _scrollView.contentSize = _imageView.frame.size;
        _scrollView.maximumZoomScale   = _maximumZoomScale;
        _scrollView.minimumZoomScale = 1.0;
        _scrollView.showsHorizontalScrollIndicator = NO;
        _scrollView.showsVerticalScrollIndicator = NO;
        _scrollView.backgroundColor = [UIColor clearColor];
        self.backgroundColor = [UIColor clearColor];
        [self addSubview:_scrollView];
        [self updateScrollView:YES];
        
        // add gesture recognizers to the image view
        UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
        UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
        UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)];
        
        [doubleTap setNumberOfTapsRequired:2];
        [twoFingerTap setNumberOfTouchesRequired:2];
        
        [_imageView addGestureRecognizer:singleTap];
        [_imageView addGestureRecognizer:doubleTap];
        [_imageView addGestureRecognizer:twoFingerTap];
        
        [singleTap release];
        [doubleTap release];
        [twoFingerTap release];
        _redoArrayImage = [[NSMutableArray alloc]init ];
        _undoArrayImage = [[NSMutableArray alloc]init ];
    }
    return self;
}
-(void) setImage:(UIImage *)image
{
    if (_imageView) {
        _imageView.image = image;
    }
}
-(UIImage*) image
{
    if (_imageView) {
        return _imageView.image;
    }
    return nil;
}
-(void) setUpWithDefaultValue
{
    _maximumZoomScale = 2.0;
}
-(UIView*) viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return _scrollView.childView;
}
-(void) flipImage:(FlipDirection)direction
{
    _currentAction = ActionFlip;
    //[self saveImageToUndo:_imageView.image];
    //_originalImage = nil;
    _originalImage = _imageView.image;
    UIImage *resultImage = _imageView.image;
    switch (direction) {
        case FlipLeft:
        {
            resultImage = [resultImage rotateInRadians:M_PI_2];
            break;
        }
        case FlipRight:
        {
            resultImage = [resultImage rotateInRadians:-M_PI_2];
            break;
        }  
        case FlipVertical:
        {
            resultImage = [resultImage verticalFlip];
            break;
        }  
        case FlipHorizontal:
        {
            resultImage = [resultImage horizontalFlip];
            break;
        }  
        default:
            break;
    }
    _imageView.image = resultImage;
    [self changeImageSizeAndUpdateScrollView];
}
-(void) preparingForCropAction
{
    if (overlapView == nil) {
        
        overlapView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _imageView.frame.size.width, _imageView.frame.size.height)];
        overlapView.backgroundColor = [UIColor clearColor];
        overlapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        
        UIView *coverView;
        coverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _imageView.frame.size.width, _imageView.frame.size.height)];
        coverView.backgroundColor = [UIColor clearColor];
        coverView.userInteractionEnabled = NO;
        coverView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [overlapView addSubview:coverView];
    }
    else overlapView.frame = CGRectMake(0, 0, _imageView.frame.size.width, _imageView.frame.size.height);
    
    if (_cropAreaSelectionView!=nil) {
        _cropAreaSelectionView.frame = CGRectMake(0, 0, _imageView.frame.size.width, _imageView.frame.size.height);
    }
    else
    {
        _cropAreaSelectionView = [[ResizableView alloc]initWithFrame:CGRectMake(0, 0, _imageView.frame.size.width, _imageView.frame.size.height)] ;
        _cropAreaSelectionView.rotationDelegate = self;
    }
    _cropAreaSelectionView.userInteractionEnabled = YES;
    [overlapView addSubview:_cropAreaSelectionView];
}
-(void) startAction: (Action) action
{
    _currentAction = action;
    [_scrollView enableGesture:NO];
   // _originalImage = nil;
    _originalImage = _imageView.image;
    switch (_currentAction) {
        case ActionFilter:      
        {
            [self applyEffect:_filter];
            break;
        }   
            //for crop and straighten action
        case ActionCrop:
        {
            [self preparingForCropAction];
            _cropAreaSelectionView.action = _currentAction;
            // Set limit for move rectangle a round
            float zoomScale = 1.0;
            CGRect rect;
            rect.origin.x = [_scrollView contentOffset].x * zoomScale;
            rect.origin.y = [_scrollView contentOffset].y * zoomScale;
            rect.size.width = [_scrollView bounds].size.width * zoomScale;
            rect.size.height = [_scrollView bounds].size.height * zoomScale;
            rect = CGRectIntersection(rect, _imageView.frame);
            _cropAreaSelectionView.displayArea = rect;
            //if (_currentAction == ActionCrop) {  
                [_cropAreaSelectionView changeResizeMethod:_resizeStrategy];
            //}
            _lastScrollViewZoomScale = [_scrollView zoomScale];
            _lastImageViewFrame = _imageView.frame;
            [overlapView bringSubviewToFront:_cropAreaSelectionView];
            [_scrollView setScrollEnabled:NO];
            [_scrollView addSubview:overlapView];
            [_scrollView bringSubviewToFront:overlapView];
            
            _maximumZoomScale = _scrollView.maximumZoomScale;
            _scrollView.minimumZoomScale =[_scrollView zoomScale];
            _scrollView.maximumZoomScale = [_scrollView zoomScale];
            _rotation =0;
            break;
        }
        default:
            break;
    }
}

-(void) finishCurrentAction
{
    switch (_currentAction) {
        case ActionFilter:
        {
            _isCanSlide = NO;
            _filter = NoneFilter;
            break;
        }
            // For crop and straighten action
        case ActionCrop:
        {
            CGRect selectionRect = _cropAreaSelectionView.selectionRect;
            float zoomScale;
            CGImageRef imageRef ;
            if (_cropAreaSelectionView.resizeMethod == Straighten) {
                zoomScale = 1.0/_lastScrollViewZoomScale;
                
            }
            else
                zoomScale =  1.0/ [_scrollView zoomScale];
            selectionRect.origin.x *= zoomScale;
            selectionRect.origin.y  *= zoomScale;
            selectionRect.size.width = selectionRect.size.width * zoomScale;
            selectionRect.size.height = selectionRect.size.height * zoomScale;
            UIImage *cropImage = _imageView.image;
            CGSize newSize;
            newSize.width = _imageView.frame.size.width*zoomScale;
            newSize.height = _imageView.frame.size.height *zoomScale;
            if (_cropAreaSelectionView.resizeMethod == Straighten) {
                cropImage = [cropImage rotateInRadians:_rotation];
                selectionRect.origin.x = newSize.width/2-selectionRect.size.width/2;
                selectionRect.origin.y = newSize.height/2-selectionRect.size.height/2;
                [_cropAreaSelectionView resetAll];
                _imageView.transform = CGAffineTransformIdentity;
            }
            cropImage = [cropImage resizedImage:newSize interpolationQuality:kCGInterpolationHigh];
            imageRef = CGImageCreateWithImageInRect([cropImage CGImage], selectionRect);
            UIImage *img = [UIImage imageWithCGImage:imageRef]; 
            CGImageRelease(imageRef);    
            _imageView.image  = img;
            [overlapView removeFromSuperview];
            [_scrollView setScrollEnabled:YES];
            [_cropAreaSelectionView removeFromSuperview];
            break;
        }
        default:
            break;
    }
    if (_originalImage) {

        [self saveImageToUndo:_originalImage];
    }
    _currentAction = ActionNone;
    [_scrollView enableGesture:YES];
    [self changeImageSizeAndUpdateScrollView];
    _originalImage = nil;
}
-(void) cancelCurrentAction
{
    if(_currentAction != ActionNone)
    {
        if (_originalImage) {
        _imageView.image = _originalImage;
        }
        switch (_currentAction) {
            case ActionFilter:
            {
                _isCanSlide = NO;
                _filter = NoneFilter;
                break;
            }   
                // for crop and straighten action
            case ActionCrop:
            {
                if (_cropAreaSelectionView.resizeMethod == Straighten) {
                    [_cropAreaSelectionView resetAll];
                    _cropAreaSelectionView.transform = CGAffineTransformIdentity;
                    _imageView.transform = CGAffineTransformIdentity;
                }
                [self changeImageSizeAndUpdateScrollView];
                [_cropAreaSelectionView removeFromSuperview];
                [overlapView removeFromSuperview];
                [_scrollView setScrollEnabled:YES];
                break;
            }
            default:
                break;
        }
        
        _originalImage = nil;
        _currentAction = ActionNone;
        [_scrollView enableGesture:YES];
        [self changeImageSizeAndUpdateScrollView];
    }
}

-(void) changeImageSizeAndUpdateScrollView
{
    CGSize imageViewSize;
    CGFloat ratio;
    [self updateScrollView:YES];
    UIImage *img = _imageView.image;
    CGSize ratioSize = CGSizeMake(img.size.width, img.size.height);
    if ((img.size.width>0 && img.size.height>0 )) {
        
        if ( img.size.width>img.size.height) {
            ratio = ratioSize.height/ratioSize.width;
            imageViewSize.width = _scrollView.frame.size.width;
            imageViewSize.height = ratio * imageViewSize.width;
        }
        else
        {
            ratio = ratioSize.width/ratioSize.height;
            imageViewSize.height = _scrollView.frame.size.height;
            imageViewSize.width = ratio * imageViewSize.height;
        }
        _imageView.frame = CGRectMake(0,0, imageViewSize.width,imageViewSize.height);
        //NSLog(@"ImageViewSize: %@", NSStringFromCGSize(imageViewSize));
    }
    
    _scrollView.contentSize = _imageView.frame.size;
    
}

-(void) rotationChange:(CGFloat)rotation
{
    _rotation -=rotation;
    _imageView.transform =  CGAffineTransformRotate(_imageView.transform, rotation);
}
-(void) updateScrollView:(BOOL) isSetZoomScale
{
    if(_imageView != nil) {
        CGSize imageSize = _imageView.image.size;
        CGSize scrollSize = _scrollView.frame.size;
        CGFloat widthRatio = scrollSize.width / imageSize.width;
        CGFloat heightRatio = scrollSize.height / imageSize.height;
        CGFloat minimumZoom = MIN(1.0, (widthRatio > heightRatio) ? heightRatio : widthRatio);
        _scrollView.minimumZoomScale = minimumZoom;
        
        if (_scrollView.maximumZoomScale != _maximumZoomScale) {
            [_scrollView setMaximumZoomScale:_maximumZoomScale];
        }
        if (isSetZoomScale) {
        [_scrollView setZoomScale:_scrollView.minimumZoomScale animated:YES];
        _lastScrollViewZoomScale = [_scrollView zoomScale];
        }
	}	
	
}
//================================================================================================
-(BOOL) isCanRedo
{
    BOOL isCanRedo = NO;
    if (_redoArrayImage && [_redoArrayImage count]>0) {
        isCanRedo = YES;
    }
    return isCanRedo;
}
-(BOOL) isCanUndo
{
    BOOL isCanUndo = NO;
    if (_undoArrayImage && [_undoArrayImage count]>0) {
        isCanUndo = YES;
    }
    return isCanUndo;
}
-(void) redo
{
    if ([self isCanRedo]) {
        UIImage *redoImage ;
        NSData *redoData = [_redoArrayImage pop];
        redoImage = [[UIImage alloc]initWithData:redoData];
//        redoImage = [_redoArrayImage pop];
        if (redoImage) {
            
            if (_undoArrayImage) {
                NSData *imageData = UIImagePNGRepresentation(_imageView.image);
                [_undoArrayImage push:imageData];
//                [_undoArrayImage push:_imageView.image];
            }
            _imageView.image = redoImage;
        }
        [redoImage release];
    }
    [self changeImageSizeAndUpdateScrollView];
}
-(void) undo
{
    if ([self isCanUndo]) {
        UIImage *undoImage ;
        NSData *redoData = [_undoArrayImage pop];
        undoImage = [[UIImage alloc]initWithData:redoData];
//        undoImage =[_undoArrayImage pop];
        if (undoImage) {
            if (_redoArrayImage) {
                NSData *imageData = UIImagePNGRepresentation(_imageView.image);
                [_redoArrayImage push:imageData];
//                [_redoArrayImage push: _imageView.image];
            }
            _imageView.image = undoImage;
        }
        [undoImage release];
    }
    [self changeImageSizeAndUpdateScrollView];
    
}
-(void) saveImageToUndo:(UIImage*) repairingImage
{
    if (_undoArrayImage) {
        [_undoArrayImage push:UIImagePNGRepresentation(repairingImage)];//, 1.0f)];
//  [_undoArrayImage push:repairingImage];
    }
    if (_redoArrayImage) {
        [_redoArrayImage removeAllObjects];
    }
}
//================================================================================================
-(void) applyEffect:(FilterAlgorithm) effect
{
    //_originalImage = _imageView.image;
    UIImage *originalImage = (UIImage*) [_originalImage copy];
    _isCanSlide = NO;

    switch (_filter) {
        case TintRed:
        {
            
            IFSimpleTintFilter *tinter = [[IFSimpleTintFilter alloc] initWithOriginalImage:originalImage];
            tinter.tintColor = [UIColor redColor];
            _imageView.image = [tinter imageWithFilterApplied];
            [tinter release];
            
            break;
        }
        case Greyscale:
        {
            IFGreyscaleFilter *grey = [[IFGreyscaleFilter alloc] initWithOriginalImage:originalImage];
            _imageView.image = [grey imageWithFilterApplied];
            [grey release];
            break;
        }
        case Pixelate :
        {
            _minimumSliderValue =1.0;
            _maximumSilderValue = 20.0;
            _currentSliderValue = 1.0;
            _isCanSlide = YES;
            [self sliderMoved:_currentSliderValue];
            break;
        }
        case Brightness:
        {
            _minimumSliderValue =-150.0;
            _maximumSilderValue = 150.0;
            _currentSliderValue = 0.0;      
            _isCanSlide = YES;
            [self sliderMoved:_currentSliderValue];
            break;
        }
        case Saturation:
        {
            _minimumSliderValue =-150.0;
            _maximumSilderValue = 150.0;
            _currentSliderValue = 0.0;
            _isCanSlide = YES;
            [self sliderMoved:_currentSliderValue];
            break;
        }
        case Hue :
        {
            _minimumSliderValue =0.0;
            _maximumSilderValue = 360.0;
            _currentSliderValue = 0.0;
            _isCanSlide = YES;
            [self sliderMoved:_currentSliderValue];
            break;
        }
        case Thermal:
        {
            IFThermalFilter *thermal = [[IFThermalFilter alloc] initWithOriginalImage:originalImage];
            _imageView.image = [thermal imageWithFilterApplied];
            [thermal release];
            break;
        }
        case SnowFuzz:
        {
            IFSnowFuzzFilter *snow = [[IFSnowFuzzFilter alloc] initWithOriginalImage:originalImage];
            _imageView.image = [snow imageWithFilterApplied];
            [snow release];
            break;
        }
        case Blur:
        {
            IFBlurFilter *blur = [[IFBlurFilter alloc] initWithOriginalImage:originalImage];
            _imageView.image = [blur imageWithFilterApplied];
            [blur release];
            break;
        }
        case FindEdges:
        {
            IFFindEdgesFilter *edges = [[IFFindEdgesFilter alloc] initWithOriginalImage:originalImage];
            _imageView.image = [edges imageWithFilterApplied];
            [edges release];
            break;
        }
        case Emboss:
        {
            IFEmbossFilter *emboss = [[IFEmbossFilter alloc] initWithOriginalImage:originalImage];
            _imageView.image = [emboss imageWithFilterApplied];
            [emboss release];
            break;
        }
        case Sharpen:
        {
            IFSharpenFilter *sharpen = [[IFSharpenFilter alloc] initWithOriginalImage:originalImage];
            _imageView.image = [sharpen imageWithFilterApplied];
            [sharpen release];
            break;
        }
        case TiltShift :
        {
            //activityView.hidden = NO;
            
            IFTiltShiftFilter *tilt = [[IFTiltShiftFilter alloc] initWithOriginalImage:originalImage];
            tilt.delegate = self;
            //imageView.image = [tilt imageWithFilterApplied];
            [tilt applyFilterOnNewThread];
            [tilt release];
            break;
        }   
        default:
            break;
    }
}
-(UIImage*) createImageFrame:(UIImage*) image bgColor:(UIColor*) color borderSize:(float) borderRatio
{
    NSInteger border;
    UIImage *resultImage;
    CGSize size = image.size;
    NSInteger borderWidth = borderRatio * size.width;
    NSInteger borderHeight = borderRatio * size.height;
    border = MIN(borderHeight, borderWidth);
    
  //  UIImage *newImage = [image resizedImage:CGSizeMake(size.width-border, size.height-border) interpolationQuality:kCGInterpolationHigh];
    
    UIGraphicsBeginImageContext(image.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor );
    CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));
    [image drawInRect:CGRectMake(border, border, size.width-2*border, size.height-2*border) blendMode:kCGBlendModeNormal alpha:1.0f];
    resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultImage;
}
-(void) borderWithStyle:(DnBorderStyle) borderStyle
{
    _originalImage = [_imageView.image retain];
    _currentAction = ActionBorderFrame;
    CGSize sizeImage = _originalImage.size;
    UIImage *mask;
    UIImage *resultImage;
    switch (borderStyle) {
        case DnBorderStyleRoundCorner:
        {
           resultImage = [_originalImage roundedCornerImage:50 borderSize:10];
            break;
        }
        case DnBorderStyleBlackRectBound:
        {
            resultImage = [self createImageFrame:_originalImage bgColor:[UIColor blackColor] borderSize:0.05f];
            break;
        } 
        case DnBorderStyleWhiteRectBound:
        {
         resultImage = [self createImageFrame:_originalImage bgColor:[UIColor whiteColor] borderSize:0.05f];   
            break;
        } 
        case DnBorderStyleSpecialStyle1:
        {
            mask = [UIImage imageNamed:@"Border_1.png"];
            resultImage = [_originalImage maskWithImage:mask withBackgroundColor:[UIColor blackColor]];
            break;
        } 
        case DnBorderStyleSpecialStyle2:
        {
            mask = [UIImage imageNamed:@"Border_2.png"];
            resultImage = [_originalImage maskWithImage:mask withBackgroundColor:[UIColor blackColor]];
            break;
        } 
        case DnBorderStyleSpecialStyle3:
        {
            mask = [UIImage imageNamed:@"Border_3.png"];
            resultImage = [_originalImage maskWithImage:mask withBackgroundColor:[UIColor blackColor]];
            break;
        }
        case DnBorderStyleSpecialStyle4:
        {
            mask = [UIImage imageNamed:@"Border_4.png"];
            NSInteger margin = 0.125*sizeImage.width;
            resultImage = [_originalImage combineWithImage:mask contentRect:CGRectMake(margin, 0,sizeImage.width-2*margin , sizeImage.height) ];
            break;
        } 
        case DnBorderStyleSpecialStyle5:
        {
            mask = [UIImage imageNamed:@"Border_5.png"];
            resultImage = [_originalImage maskWithImage:mask withBackgroundColor:[UIColor blackColor]];
            break;
        } 
        case DnBorderStyleSpecialStyle6:
        {
            mask = [UIImage imageNamed:@"Border_6.png"];
            resultImage = [_originalImage maskWithImage:mask withBackgroundColor:[UIColor blackColor]];
            break;
        } 
        default:
            break;
    }
    if (resultImage) {
        _imageView.image = resultImage;
        [self changeImageSizeAndUpdateScrollView];
    }
}
- (void) sliderMoved:(float) newValue
{
//    if (!_activityView) {
//        _activityView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
//        _activityView.frame = CGRectMake(0, 0, 160, 240);
//    }
//    [self addSubview:_activityView];
//    [self bringSubviewToFront:_activityView];
    UIImage *originalImage  =_originalImage;
    if(_filter == Pixelate)
	{
		IFPixelationFilter *pixels = [[IFPixelationFilter alloc] initWithOriginalImage:originalImage];
		pixels.pixelSize = roundf(newValue);
		_imageView.image = [pixels imageWithFilterApplied];
		[pixels release];
	}
	else if(_filter ==Brightness) 
	{
		IFBrightnessFilter *brightness = [[IFBrightnessFilter alloc] initWithOriginalImage:originalImage];
		brightness.brightnessAdjustment = roundf(newValue);
		_imageView.image = [brightness imageWithFilterApplied];
		[brightness release];
	}
	else if(_filter == Saturation) 
	{
		IFSaturationFilter *saturation = [[IFSaturationFilter alloc] initWithOriginalImage:originalImage];
		saturation.saturationAdjustment = roundf(newValue);
		_imageView.image = [saturation imageWithFilterApplied];
		[saturation release];
	}
	
	else if(_filter == Hue) 
	{
		IFHueFilter *hue = [[IFHueFilter alloc] initWithOriginalImage:originalImage];
		hue.hueAdjustment = roundf(newValue);
		_imageView.image = [hue imageWithFilterApplied];
		[hue release];
	}
//    if (!_activityView) {
//        [_activityView removeFromSuperview];
//    }
}
#pragma mark - Filter Delegate

- (void) filterDidApplyWithResult:(UIImage *)result
{
	//activityView.hidden = YES;
	_imageView.image = result;
}
//================================================================================================
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_isCanSlide) {
        _lastTouchPosition = [[touches anyObject] locationInView:self];
    }
    
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_isCanSlide) {
        CGPoint currentPosition = [[touches anyObject] locationInView:self];
        CGFloat distance = currentPosition.x - _lastTouchPosition.x;
        float unit = (_maximumSilderValue - _minimumSliderValue) /self.frame.size.width;
        distance = distance *unit;
       // NSLog(@"distance: %f", distance);
        float newValue=_currentSliderValue;
        newValue +=distance;
        
        if (newValue<_minimumSliderValue)
        {
            newValue = _minimumSliderValue;
        }
        if( newValue>_maximumSilderValue) {
            newValue = _maximumSilderValue;
        }
        //NSLog(@"newValue: %f", newValue);
        _currentSliderValue = newValue;
        _lastTouchPosition = currentPosition;
        [self sliderMoved:newValue];
    }
}
//================================================================================================

#pragma mark TapDetectingImageViewDelegate methods

- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {
    // single tap does nothing for now
}

- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
    // zoom in
    float newScale = [_scrollView zoomScale] * ZOOM_STEP;
    CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
    [_scrollView zoomToRect:zoomRect animated:YES];
}

- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer {
    
    // two-finger tap zooms out
    float newScale = [_scrollView zoomScale] / ZOOM_STEP;
    CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
    [_scrollView zoomToRect:zoomRect animated:YES];
}

#pragma mark Utility methods

- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
    
    CGRect zoomRect;
    
    // the zoom rect is in the content view's coordinates. 
    //    At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
    //    As the zoom scale decreases, so more content is visible, the size of the rect grows.
    zoomRect.size.height = [_scrollView frame].size.height / scale;
    zoomRect.size.width  = [_scrollView frame].size.width  / scale;
    
    // choose an origin so as to get the right center.
    zoomRect.origin.x    = center.x - (zoomRect.size.width  / 2.0);
    zoomRect.origin.y    = center.y - (zoomRect.size.height / 2.0);
    
    return zoomRect;
}

- (void)dealloc
{
    [super dealloc];
}

@end
